“h5_extend18”

Information

The example shown in this file appears at: http://www.hdfgroup.org/HDF5/Tutor/extend.html (accessed 10 July 2011)

The example shown in this file is following the tutorial: http://www.hdfgroup.org/HDF5/Tutor/introductory.html

Good references for the shown HDF5 functions include:
http://www.hdfgroup.org/HDF5/doc/RM/RM_H5Front.html
http://www.hdfgroup.org/HDF5/doc/RM/

Prepared 10 July 2011 by Scot Martin for Windows 7, 64-bit, Mathematica version 8.0.1.

“c” code we seek to replicate in this example

/**************************************************************  
 *
 *   This example shows how to work with extendible datasets.
 *   In the current version of the library a dataset MUST be
 *   chunked in order to be extendible.  
 *
 *   This example is derived from the h5_extend_write.c and 
 *   h5_read_chunk.c examples that are in the "Introduction 
 *   to HDF5".
 *   
 *************************************************************/
 
#include "hdf5.h"

#define FILE        "ext.h5"
#define DATASETNAME "ExtendibleArray" 
#define RANK         2

int
main (void)
{
    hid_t       file;                          /* handles */
    hid_t       dataspace, dataset;  
    hid_t       filespace;                   
    hid_t       cparms;                     
    hid_t       memspace;

    hsize_t      dims[2]  = { 3, 3};           /* dataset dimensions			
                                                  at creation time */
    hsize_t      dims1[2] = { 3, 3};           /* data1 dimensions */ 
    hsize_t      dims2[2] = { 7, 1};           /* data2 dimensions */  

    hsize_t      maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED};
    hsize_t      size[2];
    hsize_t     offset[2];
    hsize_t      i,j;
    herr_t       status, status_n;                             
    int          data1[3][3] = { {1, 1, 1},      /* data to write */
                                 {1, 1, 1},
                                 {1, 1, 1} };      

    int          data2[7]    = { 2, 2, 2, 2, 2, 2, 2};

    /* Variables used in reading data back */
    hsize_t      chunk_dims[2] ={2, 5};
    hsize_t      chunk_dimsr[2];
    hsize_t      dimsr[2];
    int          data_out[10][3];
    int          rank, rank_chunk;

    /* Create the data space with unlimited dimensions. */
    dataspace = H5Screate_simple (RANK, dims, maxdims); 

    /* Create a new file. If file exists its contents will be overwritten. */
    file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

    /* Modify dataset creation properties, i.e. enable chunking  */
    cparms = H5Pcreate (H5P_DATASET_CREATE);
    status = H5Pset_chunk ( cparms, RANK, chunk_dims);

    /* Create a new dataset within the file using cparms
       creation properties.  */
    dataset = H5Dcreate (file, DATASETNAME, H5T_NATIVE_INT, dataspace,
                         H5P_DEFAULT, cparms, H5P_DEFAULT);

    /* Extend the dataset. This call assures that dataset is 3 x 3.*/
    size[0]   = 3; 
    size[1]   = 3; 
    status = H5Dextend (dataset, size);

    /* Select a hyperslab  */
    filespace = H5Dget_space (dataset);
    offset[0] = 0;
    offset[1] = 0;
    status = H5Sselect_hyperslab (filespace, H5S_SELECT_SET, offset, NULL,
                                  dims1, NULL);  

    /* Write the data to the hyperslab  */
    status = H5Dwrite (dataset, H5T_NATIVE_INT, dataspace, filespace,
                       H5P_DEFAULT, data1);

    /* Extend the dataset. Dataset becomes 10 x 3  */
    dims[0]   = dims1[0] + dims2[0];
    size[0]   = dims[0];  
    size[1]   = dims[1]; 
    status = H5Dextend (dataset, size);

    /* Select a hyperslab  */
    filespace = H5Dget_space (dataset);
    offset[0] = 3;
    offset[1] = 0;
    status = H5Sselect_hyperslab (filespace, H5S_SELECT_SET, offset, NULL,
                                  dims2, NULL);  

    /* Define memory space */
    dataspace = H5Screate_simple (RANK, dims2, NULL); 

    /* Write the data to the hyperslab  */
    status = H5Dwrite (dataset, H5T_NATIVE_INT, dataspace, filespace,
                       H5P_DEFAULT, data2);

    /* Close resources */
    status = H5Dclose (dataset);
    status = H5Sclose (dataspace);
    status = H5Sclose (filespace);
    status = H5Fclose (file);

/****************************************************************
    Read the data back 
 ***************************************************************/

    file = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT);
    dataset = H5Dopen (file, DATASETNAME, H5P_DEFAULT);
    filespace = H5Dget_space (dataset);
    rank = H5Sget_simple_extent_ndims (filespace);
    status_n = H5Sget_simple_extent_dims (filespace, dimsr, NULL);

    cparms = H5Dget_create_plist (dataset);
    if (H5D_CHUNKED == H5Pget_layout (cparms))
    {
       rank_chunk = H5Pget_chunk (cparms, 2, chunk_dimsr);
    }

    memspace = H5Screate_simple (rank,dimsr,NULL);
    status = H5Dread (dataset, H5T_NATIVE_INT, memspace, filespace,
                      H5P_DEFAULT, data_out);

    printf("\n");
    printf("Dataset: \n");
    for (j = 0; j < dimsr[0]; j++)
    {
       for (i = 0; i < dimsr[1]; i++)
           printf("%d ", data_out[j][i]);
       printf("\n");
    }

    status = H5Pclose (cparms);
    status = H5Dclose (dataset);
    status = H5Sclose (filespace);
    status = H5Sclose (memspace);
    status = H5Fclose (file);
}

Implementation in Mathematica

set up

SetDirectory[NotebookDirectory[]]

Needs["HDF5`"]

data1=Table[3,{3},{3}]

data2=ConstantArray[2,7]

file=FileNameJoin[{Directory[],"ext.h5"}]

write out file

fileID=H5Fcreate[file,H5FuACCuTRUNC,H5PuDEFAULT,H5PuDEFAULT]

first data set

dataSpaceID = H5ScreateUsimple[2,{3,3},{H5SuUNLIMITED,H5SuUNLIMITED}]

H5Pcreate does not work. It seems that using the value of 4 for H5PuDATASETuCREATE as inferred from DotNet implementation is not the way to do things. The workaround is to go straight to DotNet for needed purpose.

cparmsID=H5P`create[H5P`PropertyListClass`DATASETUCREATE]@Id[]

H5PsetChunk[cparmsID,2,{2,5}]

dataSetID=H5Dcreate[fileID,"IntArray",H5T`copy[H5TuSTDuI32BE]@Id[],dataSpaceID,H5PuDEFAULT,cparmsID,H5PuDEFAULT]

(* H5Dextend is deprecated for this new function *)
H5DsetExtent[dataSetID,{3,3}]

fileSpaceID=H5DgetSpace[dataSetID]

H5SselectHyperSlab[fileSpaceID,H5SuSET,{0,0},Null,{3,3},Null]

H5Dwrite[Integer32][dataSetID,H5T`copy[H5TuNATIVEuINT]@Id[],dataSpaceID,fileSpaceID,H5PuDEFAULT,Flatten@data1]

H5Sclose[dataSpaceID];
H5Sclose[fileSpaceID]

second data set

H5DsetExtent[dataSetID,{10,3}]

fileSpaceID=H5DgetSpace[dataSetID]

H5SselectHyperSlab[fileSpaceID,H5SuSET,{3,0},Null,{7,1},Null]

dataSpaceID = H5ScreateUsimple[2,{7,1},Null]

H5Dwrite[Integer32][dataSetID,H5T`copy[H5TuNATIVEuINT]@Id[],dataSpaceID,fileSpaceID,H5PuDEFAULT,Flatten@data2]

H5Dclose[dataSetID]
H5Sclose[fileSpaceID]
H5Sclose[dataSpaceID]
H5Fclose[fileID]

data back in

fileID=H5Fopen[file,H5FuACCuRDONLY,H5PuDEFAULT];

dataSetID=H5Dopen[fileID,"IntArray",H5PuDEFAULT];

fileSpaceID=H5DgetSpace[dataSetID];

rank=H5SgetSimpleExtentNDims[fileSpaceID]

dimsList=Table[0,{rank}];
dimsList[[1]]=NETNew["System.Int64[]",rank];
dimsList[[2]]=NETNew["System.Int64[]",rank];
H5SgetSimpleExtentDims[fileSpaceID,dimsList[[1]],dimsList[[2]]]

NETObjectToExpression/@dimsList

cparmsID=H5DgetCreatePList[dataSetID]

memorySpaceID=H5ScreateUsimple[rank,dimsList[[1]],Null]

readDataObject=NETNew["System.Int32[]",Times@@NETObjectToExpression@dimsList[[1]]]

H5Dread[Integer32][dataSetID,H5T`copy[H5TuNATIVEuINT]@Id[],memorySpaceID,fileSpaceID,H5PuDEFAULT,readDataObject]

Partition[NETObjectToExpression@readDataObject,3]

%//TableForm

H5Pclose[cparmsID]
H5Dclose[dataSetID]
H5Sclose[fileSpaceID]
H5Sclose[memorySpaceID]
H5Fclose[fileID]